package com.example.fastshare;

import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import com.example.fastshare.adapter.DBMesssageAdapter;
import com.example.fastshare.adapter.DBUserAdapter;
import com.example.fastshare.alljoyn.*;
import com.example.fastshare.alljoyn.Package;
import com.example.fastshare.entities.MessageEntity;
import com.example.fastshare.entities.UserEntity;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v4.app.FragmentManager.OnBackStackChangedListener;
import android.text.Editable;
import android.text.Layout;
import android.text.TextWatcher;
import android.text.format.DateFormat;
import android.text.format.Time;
import android.util.Log;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.view.View.OnLongClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.QuickContactBadge;
import android.widget.TextView;

public class ConversationActivity extends Activity implements Observer {

	public static final int CHOOSE_IMAGE = 10;
	private static final float ImageSize = 0.12f;
	public ArrayList<Item> _list = null;
	public ListItemAdapter _listAdapter = null;
	private static final int HANDLE_HISTORY_CHANGED_EVENT = 6;
	private static final int UPDATE_HISTORY = 7;
	private Uri m_imagePath;
	private MainApp m_mainApp;
	public boolean m_isSendImage = false;
	private Button m_btnSend;
	private EditText m_txtMessage;
	private ListView m_listChat;
	private TextView m_contactName;
	private LinearLayout m_contentSendingLayout;
	private ImageButton m_btnSetImage;
	private ImageView m_imageSend;
	private QuickContactBadge m_avatarImage;

	private UserEntity m_user = null;

	private Boolean m_isLoadFromHistory = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		setContentView(R.layout.activity_conversation);

		m_contentSendingLayout = (LinearLayout) findViewById(R.id.activity_conversation_footer_fullscreen_content_controls);
		m_contactName = (TextView) findViewById(R.id.activity_conversation_header_textview);
		m_imageSend = (ImageView) findViewById(R.id.imageViewSend);
		m_avatarImage = (QuickContactBadge) findViewById(R.id.activity_conversation_header_contact_imageButton);

		m_imageSend.setOnLongClickListener(new OnLongClickListener() {

			@Override
			public boolean onLongClick(View v) {
				setSendingImageModeOff();
				return true;
			}
		});
		Intent intent = getIntent();
		DBUserAdapter getUser = new DBUserAdapter(this);
		
		String messageIntent = intent.getStringExtra("UserInfo");
		String [] split = messageIntent.split("_");
		if (split.length == 1) {
			m_isLoadFromHistory = true;
			m_user = getUser.getUserByID(split[0]);
			if (m_user != null) {
				m_contactName.setText(m_user.getName());
				LoadAvatar();
				LoadHistory();
			} else {
				m_contactName.setText("Error :( ");
			}
		} else {
			m_user = getUser.getUserByID(split[0]);
			if (m_user != null) {
				m_contactName.setText(m_user.getName());
				LoadAvatar();
				LoadHistory();
			} else {
				m_contactName.setText("Error :( ");
			}
		}

		final View headerControlsView = findViewById(R.id.activity_conversation_header_fullscreen_content_controls);
		final View footerControlsView = findViewById(R.id.activity_conversation_footer_fullscreen_content_controls);
		m_btnSend = (Button) findViewById(R.id.activity_conversation_footer_send_Button);
		m_txtMessage = (EditText) findViewById(R.id.activity_conversation_footer_inputText_editText);
		m_listChat = (ListView) findViewById(R.id.activity_conversation_listMessage);
		m_btnSetImage = (ImageButton) findViewById(R.id.activity_conversation_footer_inputImage_imageButton);
		m_txtMessage.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			@Override
			public void afterTextChanged(Editable s) {
				if (m_txtMessage.getText().toString() == null
						|| m_txtMessage.getText().toString().equals("")) {
					m_btnSend.setVisibility(0);
				} else
					m_btnSend.setVisibility(1);
			}
		});

		// new AsynTaskForLoadingMessage(this).execute();
		setSendingImageModeOff();
		
		if(m_isLoadFromHistory)
		{
			m_btnSend.setEnabled(false);
			m_btnSetImage.setEnabled(false);
			m_txtMessage.setEnabled(false);
		}
		super.onCreate(savedInstanceState);
		_listAdapter = new ListItemAdapter(this,
				android.R.layout.activity_list_item, _list);

		m_listChat.setAdapter(_listAdapter);
		m_listChat.setClickable(false);
		scrollMyListViewToBottom();
		ImageButton backBtn = (ImageButton) findViewById(R.id.activity_conversation_header_back_imageButton);
		backBtn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				finish();
				onBackPressed();
			}
		});

		m_mainApp = (MainApp) getApplication();
		m_mainApp.chechIn();
		m_mainApp.addObserver(this);

	}

	public void btnSendImage_Clicked(View v) {
		Intent intent = new Intent(Intent.ACTION_PICK,
				android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
		startActivityForResult(intent, CHOOSE_IMAGE);

	}

	public void btnSend_Clicked(View v) {
		if (!m_txtMessage.getText().toString().isEmpty() && !m_isSendImage) {
			// new AsyncTaskForSending(this, m_Handler).execute();
			Send();
			m_txtMessage.setText("");
			m_btnSend.setVisibility(0);
			// updateListChat();
		} else {
			if (m_isSendImage) {
				// new AsyncTaskForSending(this, m_Handler).execute();
				Send();
				m_txtMessage.setText("");
				m_imageSend.setVisibility(View.INVISIBLE);
				// updateListChat();
			}
		}
		m_isSendImage = false;
	}

	public synchronized String GetPathFile() {
		String pathName;
		String[] proj = { MediaStore.Images.Media.DATA };
		@SuppressWarnings("deprecation")
		Cursor cursor = managedQuery(m_imagePath, proj, null, null, null);
		int column_index = cursor
				.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		cursor.moveToFirst();
		pathName = cursor.getString(column_index);
		return pathName;
	}

	@Override
	public synchronized void update(Observable obs, Object obj) {
		String qualifier = (String) obj;
		if (qualifier.equals(m_mainApp.HISTORY_CHANGED_EVENT)) {
			Message message = m_Handler
					.obtainMessage(HANDLE_HISTORY_CHANGED_EVENT);
			m_Handler.sendMessage(message);
		}

	}

	private synchronized Boolean updateListChat() {
		try {
			ArrayList<Package> messages = m_mainApp.getM_listHistory();
			if (messages.size() != 0) {
				if (m_mainApp.CheckSendStatus()) {
					if (m_mainApp.getWaitPackage().m_type.equals("IMAGE")) {
						if (m_mainApp.getWaitPackage().m_status.equals("DONE")) {

							ArrayList<Image> listImage = new ArrayList<Image>();
							for (Package pac : messages) {
								if (pac.m_packageName.equals(m_mainApp
										.getWaitPackage().m_description)) {
									Image img = new Image();
									img = pac.getImage();
									listImage.add(img);
								}
							}
							if (m_mainApp.getWaitPackage() != null
									&& m_mainApp.getWaitPackage().m_sender
											.equals(m_mainApp.m_userInfo
													.getM_macAddress())) {

								Item image = new Item(
										MainApp.m_userInfo.getM_avatar(), null,
										new Time(), true);
								image.setImage(m_mainApp.getWaitPackage().m_description);
								MessageEntity saveMessage = new MessageEntity(
										UUID.randomUUID().toString(), false,
										m_user.getID(), "", image.getImageID(),
										"", new Time());
								new AsyncTaskForSaveMessage(this, saveMessage)
										.execute();
								_listAdapter.add(image);
								_listAdapter.notifyDataSetChanged();
								scrollMyListViewToBottom();

							} else {
								if (m_mainApp.getWaitPackage() != null) {
									Item image = new Item(
											m_user.getAvatar_Path(), null,
											new Time(), false);
									image.SaveImage(Utilities
											.createBitmapFromList(listImage),
											m_mainApp.getWaitPackage().m_sender);
									MessageEntity saveMessage = new MessageEntity(
											UUID.randomUUID().toString(), true,
											m_user.getID(), "",
											image.getImageID(), "", new Time());
									new AsyncTaskForSaveMessage(this,
											saveMessage).execute();
									_listAdapter.add(image);
									_listAdapter.notifyDataSetChanged();
									scrollMyListViewToBottom();
								}
							}
							m_mainApp.removeHistoryItem();
							m_mainApp.removeWaitPackage();
							return true;
						}

					} else {
						if (m_mainApp.getWaitPackage().m_type.equals("MESSAGE")) {
							if (m_mainApp.getWaitPackage().m_status
									.equals("DONE")) {
								for (Package pac : messages) {
									if (pac.m_packageName.equals(m_mainApp
											.getWaitPackage().m_description)) {
										String message;
										try {
											message = pac.GetMessage();
											if (m_mainApp.getWaitPackage() != null
													&& m_mainApp
															.getWaitPackage().m_sender
															.equals(m_mainApp.m_userInfo
																	.getM_macAddress())) {
												MessageEntity saveMessage = new MessageEntity(
														UUID.randomUUID()
																.toString(),
														false, m_user.getID(),
														"", "", message,
														new Time());
												new AsyncTaskForSaveMessage(
														this, saveMessage)
														.execute();
												_listAdapter.add(new Item(
														MainApp.m_userInfo
																.getM_avatar(),
														message, new Time(),
														true));
												_listAdapter
														.notifyDataSetChanged();
												scrollMyListViewToBottom();
											} else {
												if (m_mainApp.getWaitPackage() != null) {
													MessageEntity saveMessage = new MessageEntity(
															UUID.randomUUID()
																	.toString(),
															true, m_user
																	.getID(),
															"", "", message,
															new Time());
													new AsyncTaskForSaveMessage(
															this, saveMessage)
															.execute();
													_listAdapter
															.add(new Item(
																	m_user.getAvatar_Path(),
																	message,
																	new Time(),
																	false));
													_listAdapter
															.notifyDataSetChanged();
													scrollMyListViewToBottom();
												}
											}

										} catch (UnsupportedEncodingException e) {

											message = e.toString();
										}
									}
								}
								m_mainApp.removeHistoryItem();
								m_mainApp.removeWaitPackage();
								return true;
							}
						}
					}
				}
			}
		} catch (OutOfMemoryError e) {
			Log.e("Error", e.toString());
			return false;
		}
		return true;
	}

	private Handler m_Handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case HANDLE_HISTORY_CHANGED_EVENT: {
				updateListChat();
				break;
			}
			default:
				break;
			}
		}
	};

	private void UpdateThread() {
		new AsyncTaskForUpdate(this).execute();
	}

	@Override
	public void onDestroy() {
		m_mainApp.deleteObserver(this);
		super.onDestroy();
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		switch (requestCode) {
		case CHOOSE_IMAGE: {
			if (resultCode == Activity.RESULT_OK) {
				m_isSendImage = true;
				m_imagePath = data.getData();
				setSendingImageModeOn();
				m_imageSend.setImageBitmap(Utilities.getImageLocal(
						GetPathFile(), 200, 150));
				m_btnSend.setEnabled(true);
				m_btnSend.setVisibility(View.VISIBLE);
			}
		}
			break;
		case ConnectionsFragment.START_CONVERSATION_MODE: {
			if (resultCode == Activity.RESULT_OK) {
				DBUserAdapter getUser = new DBUserAdapter(this);
				m_user = getUser.getUserByID(data.getStringExtra("UserInfo"));
				if (m_user != null) {
					m_contactName.setText(m_user.getName());
					LoadHistory();
				} else {
					m_contactName.setText("Error :( ");
				}
			}
		}
			break;
		default:
			break;
		}

	}

	public Boolean LoadHistory() {
		DBMesssageAdapter messageAdapter = new DBMesssageAdapter(this);
		List<MessageEntity> result = messageAdapter.getMessagesOfUser(m_user
				.getID());
		List<MessageEntity> lastTenMessage = new ArrayList<MessageEntity>();
		_list = new ArrayList<Item>();
		if (result == null) {
			return false;
		} else {
			int size = result.size() - 10;
			int count = 0;
			for (MessageEntity messUser : result) {
				if (count > size - 1) {
					lastTenMessage.add(messUser);
				}
				count++;
			}
			if (lastTenMessage.size() != 0) {
				if (_list == null) {
					_list = new ArrayList<Item>();
				}
				for (MessageEntity messUser : lastTenMessage) {
					if (messUser.getContent().equals("")) {
						if (messUser.getMessage_type().equals("SEND")) {
							Item item = new Item(m_user.getAvatar_Path(), "",
									null, false);
							item.setImage(messUser.getImage_ID());
							item.setStrTime(messUser.getTimeInString());
							_list.add(item);

						} else {
							Item item = new Item(
									MainApp.m_userInfo.getM_avatar(), "", null,
									true);
							item.setImage(messUser.getImage_ID());
							item.setStrTime(messUser.getTimeInString());
							_list.add(item);

						}
					} else {
						if (messUser.getMessage_type().equals("SEND")) {
							Item item = new Item(m_user.getAvatar_Path(),
									messUser.getContent(), null, false);
							item.setStrTime(messUser.getTimeInString());
							_list.add(item);

						} else {
							Item item = new Item(
									MainApp.m_userInfo.getM_avatar(),
									messUser.getContent(), null, true);
							item.setStrTime(messUser.getTimeInString());
							_list.add(item);
						}
					}

				}
			}
			return true;
		}
	}

	private Time setStringToTime(String strTime) {
		return new Time(strTime);
	}

	public Boolean SaveConversation(MessageEntity message) {
		DBMesssageAdapter messageAdapter = new DBMesssageAdapter(this);
		long result = messageAdapter.insertMessage(message);
		if (result != -1) {
			Log.i("Save Message", "Save OK" + message.getID());
			return true;
		} else {
			Log.i("Save Message", "Save Error" + message.getID());
			return false;
		}
	}

	public synchronized Boolean Send() {
		if (m_isSendImage) {
			List<Image> listSend;
			listSend = new ArrayList<Image>();
			List<Package> listPackage = new ArrayList<Package>();
			try {
				listSend = Utilities.SplitBitmap(GetPathFile(),
						Utilities.getImageLocal(GetPathFile(), 50));
				PackageDetail pacDe = new PackageDetail();
				pacDe.m_sender = m_mainApp.m_userInfo.getM_macAddress();
				pacDe.m_description = GetPathFile();
				pacDe.m_status = "SENDING";
				pacDe.m_type = "IMAGE";

				for (Image img : listSend) {
					Package pac = new Package();
					pac.m_id = Integer.toString(img.getM_row());
					pac.m_listPackage = new DataPackage[img.getM_imageColumn()
							.size()];
					pac.m_size = img.getM_imageColumn().size();
					pac.m_packageName = GetPathFile();
					pac.m_status = "SENDING";
					pac.m_type = "IMAGE";
					pac.addPackageImage(img);
					listPackage.add(pac);
				}
				pacDe.createPackageDetail(listPackage);
				m_mainApp.addRemotePackageDetail(pacDe);
				for (Package pac : listPackage) {
					m_mainApp.localUserMessage(pac);
					Log.i("Sending", "Package: " + pac.m_id);
				}
				m_isSendImage = false;
				setSendingImageModeOff();
				return true;
			} catch (Exception e) {
				Log.e("Error", e.toString());
				m_isSendImage = false;
				setSendingImageModeOff();
				return false;
			}
		} else {
			if (!m_txtMessage.getText().toString().equals("")) {
				String _message = m_txtMessage.getText().toString();
				PackageDetail pacDe = new PackageDetail();
				pacDe.m_sender = m_mainApp.m_userInfo.getM_macAddress();
				pacDe.m_description = _message;
				pacDe.m_status = "SENDING";
				pacDe.m_type = "MESSAGE";
				Package pac = new Package();
				pac.m_id = UUID.randomUUID().toString();
				pac.m_listPackage = new DataPackage[1];
				pac.m_size = 1;
				pac.m_packageName = _message;
				pac.m_status = "SENDING";
				pac.m_type = "MESSAGE";
				pac.addPackageString(_message);
				pacDe.createPackageDetail(pac);
				m_mainApp.addRemotePackageDetail(pacDe);

				try {
					m_mainApp.localUserMessage(pac);
					return true;
				} catch (UnsupportedEncodingException e) {

					Log.e("Error", e.toString());
					m_isSendImage = false;
					return false;
				}
			}

		}
		System.gc();
		return true;
	}

	private synchronized void scrollMyListViewToBottom() {
		m_listChat.post(new Runnable() {
			@Override
			public void run() {
				// Select the last row so it will scroll into view...
				m_listChat.setSelection(_listAdapter.getCount() - 1);
			}
		});
	}

	public void setSendingImageModeOn() {
		m_contentSendingLayout.setLayoutParams(new LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 0.12f));
		m_imageSend.setVisibility(View.VISIBLE);
		m_txtMessage.setVisibility(View.INVISIBLE);
		m_isSendImage = true;
	}

	public void setSendingImageModeOff() {
		m_contentSendingLayout.setLayoutParams(new LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 0.0f));
		m_imageSend.setVisibility(View.INVISIBLE);
		m_txtMessage.setVisibility(View.VISIBLE);
		m_isSendImage = false;
	}

	public void LoadAvatar() {
		if (m_user.getAvatar_Path().equals("1")) {
			m_avatarImage.setImageResource(R.drawable.a);
		}
		if (m_user.getAvatar_Path().equals("2")) {
			m_avatarImage.setImageResource(R.drawable.b);
		}
		if (m_user.getAvatar_Path().equals("3")) {
			m_avatarImage.setImageResource(R.drawable.c);
		}
	}

	public class AsyncTaskForSending extends AsyncTask<Void, Boolean, Boolean> {

		@Override
		protected Boolean doInBackground(Void... params) {
			if (activity.Send()) {
				return true;
			}
			return false;
		}

		@Override
		protected void onPostExecute(Boolean result) {

			super.onPostExecute(result);
			/*
			 * if (result) { Message message = m_Handler
			 * .obtainMessage(HANDLE_HISTORY_CHANGED_EVENT);
			 * m_Handler.sendMessage(message); }
			 */
		}

		private ConversationActivity activity;
		private Handler m_handler;

		public AsyncTaskForSending(ConversationActivity _activity, Handler in) {
			activity = _activity;
			m_handler = in;
		}

	}

	public class AsyncTaskForUpdate extends AsyncTask<Void, Boolean, Boolean> {

		@Override
		protected Boolean doInBackground(Void... params) {

			if (activity.updateListChat())
				return true;
			return false;
		}

		@Override
		protected void onPostExecute(Boolean result) {

			super.onPostExecute(result);
		}

		private ConversationActivity activity;

		public AsyncTaskForUpdate(ConversationActivity _activity) {
			activity = _activity;
		}
	}

	public class AsyncTaskForSaveMessage extends AsyncTask<Void, Void, Boolean> {

		ConversationActivity m_activity;
		MessageEntity m_message;

		@Override
		protected Boolean doInBackground(Void... params) {
			// TODO Auto-generated method stub
			return m_activity.SaveConversation(m_message);
		}

		public AsyncTaskForSaveMessage(ConversationActivity activity,
				MessageEntity message) {
			this.m_activity = activity;
			this.m_message = message;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		@Override
		protected void onPostExecute(Boolean result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPreExecute()
		 */
		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
		}

	}

	public class AsynTaskForLoadingMessage extends
			AsyncTask<Void, Void, Boolean> {

		ConversationActivity activity;

		@Override
		protected Boolean doInBackground(Void... params) {
			// TODO Auto-generated method stub
			return activity.LoadHistory();
		}

		public AsynTaskForLoadingMessage(ConversationActivity ac) {
			this.activity = ac;
		}

	}

}
